#include "std_output.h"
#include <iostream>
#include <string.h>
#include "background.h"
#include "console_color.h"
#include "feature.h"
#include "language.h"
#include "scenario.h"
#include "step.h"
#include "step_definition.h"

using namespace CppStory;

void StdOutput::output_feature(Feature* feature)
{
    std::cout << std::endl;
    std::cout << white;
    std::cout << Language::instance()->get_feature_str() << ": ";
    std::cout << feature->get_feature_name();

    std::cout << grey;
    std::cout << " # " << feature->get_file() << ":" << feature->get_line() << std::endl;

    std::cout << white;
    std::cout << "  " << Language::instance()->get_in_order_str() << " ";
    std::cout << feature->get_in_order() << std::endl;

    std::cout << "  " << Language::instance()->get_as_str() << " ";
    std::cout << feature->get_who() << std::endl;

    std::cout << "  " << Language::instance()->get_i_want_str() << " ";
    std::cout << feature->get_want() << std::endl;
}

void StdOutput::output_background(Background* background)
{
    std::cout << green;
    std::cout << "    " << Language::instance()->get_background_str() << ":";
    std::cout << std::endl;
}

void StdOutput::output_scenario(Scenario* scenario)
{
    std::cout << green;
    std::cout << "  " << Language::instance()->get_scenario_str() << ": ";
    std::cout << scenario->get_name();

    std::cout << grey;
    std::cout << " # " << scenario->get_file() << ":" << scenario->get_line() << std::endl;
}

void StdOutput::output_step(Step* step, StepDefinition* step_def, RESULT_TYPE result)
{
    switch (result)
    {
        case RT_SUCCESSFUL:
            std::cout << green;
            break;
        case RT_UNDEFINED:
            std::cout << yellow;
            break;
        case RT_SKIPPED:
            std::cout << cyan;
            break;
        case RT_FAILED:
            std::cout << red;
            break;
    }
    if (0 == strcmp("Given", step->get_type()))
        std::cout << "      " << Language::instance()->get_given_str() << " ";
    else if (0 == strcmp("And", step->get_type()))
        std::cout << "      " << Language::instance()->get_and_str() << " ";
    else if (0 == strcmp("When", step->get_type()))
        std::cout << "      " << Language::instance()->get_when_str() << " ";
    else if (0 == strcmp("Then", step->get_type()))
        std::cout << "      " << Language::instance()->get_then_str() << " ";
    else if (0 == strcmp("But", step->get_type()))
        std::cout << "      " << Language::instance()->get_but_str() << " ";
    std::cout << step->get_name();

    std::cout << grey;
    if (NULL == step_def)
        std::cout << " # " << step->get_file() << ":" << step->get_line();
    else
        std::cout << " # " << step_def->get_file() << ":" << step_def->get_line();

    std::cout << red;
    if (RT_FAILED == result)
    {
        std::cout << std::endl;
        std::cout << "        " << step_def->get_failed_file() << ":" << step_def->get_failed_line()
                  << " " << step_def->get_failed_message();
    }

    std::cout << normal;
    std::cout << std::endl;
}

void StdOutput::output_ambiguous_step(Step* step, StepDefinition* first, StepDefinition* second)
{
    std::cout << red;
    std::cout << "\t\terror: ambiguous step" << std::endl;
    std::cout << "\t\t" << step->get_type() << ":\t" << step->get_name() << std::endl;
    std::cout << "\t\t\t(" << step->get_file()
                           << "<"
                           << step->get_line()
                           << ">)" << std::endl;
    std::cout << "\t\t\t(first " << first->get_file()
                           << "<"
                           << first->get_line()
                           << ">)" << std::endl;
    std::cout << "\t\t\t(second " << second->get_file()
                           << "<"
                           << second->get_line()
                           << ">)" << std::endl;
    std::cout << normal;
}

void StdOutput::output_feature_summary(int total, int failed_count)
{
    std::cout << normal;
    std::cout << "feature (failed/total): \t";

    if (failed_count > 0)
        std::cout << red;
    std::cout << failed_count;

    std::cout << normal;
    std::cout << "/" << total;

    std::cout << std::endl;
}

void StdOutput::output_scenario_summary(int total, int failed_count)
{
    std::cout << std::endl;
    std::cout << normal;
    std::cout << "scenario  (failed/total): \t";

    if (failed_count > 0)
        std::cout << red;
    std::cout << failed_count;

    std::cout << normal;
    std::cout << "/" << total;

    std::cout << std::endl;
}

